#include <assert.h>
#include <imbus.h>
#include <stdio.h>
#include <string.h>

int main (int argc, char *argv [])
{
    IMMemoryChunk *chunk1;
    IMMemoryChunk *chunk2;
    IMMemoryChunk *chunk3;
    IMMemoryChunk *chunk4;
    IMMemoryChunk *chunk5;
    IMChar        *ptr;
    IMSize         i;
    IMIOChannel   *channel;
    IMIOError      error;

    im_init (&argc, &argv);

    chunk1 = im_memory_chunk_new (256);
    chunk2 = im_memory_chunk_new (0);

    if (!chunk1 || im_memory_chunk_get_size (chunk1) != 256) {
        printf ("Failed to create chunk1 (256)\n");
        return 1;
    }

    if (!chunk2 || im_memory_chunk_get_size (chunk2) != 0) {
        printf ("Failed to create chunk2 (0)\n");
        return 1;
    }

    ptr = (IMChar *) im_memory_chunk_get_ptr (chunk1);
    printf ("Chunk1: ptr = %p  size = %d\n", ptr, im_memory_chunk_get_size (chunk1));

    for (i = 0; i < 255; ++i)
        *ptr++ = (IMChar) i;

    *ptr = 0;

    channel = im_io_channel_new_file ("chunk1", "w", 0);

    if (!im_memory_chunk_save (chunk1, channel, -1, NULL, &error)) {
        printf ("Failed to save chunk1.\n");
        return 1;
    }
    im_object_unref (channel);

    channel = im_io_channel_new_file ("chunk1", "r", 0);

    if (!im_memory_chunk_load (chunk2, channel, -1, NULL, &error)) {
        printf ("Failed to load chunk1 file into chunk2.\n");
        return 1;
    }
    im_object_unref (channel);

    printf ("Chunk2 (mmap): ptr = %p  size = %d\n",
        im_memory_chunk_get_const_ptr (chunk2), im_memory_chunk_get_size (chunk2));

    chunk3 = im_object_clone (chunk2);

    if (!chunk3) {
        printf ("Failed to clone chunk2 to chunk3.\n");
        return 1;
    }

    printf ("Chunk3 (clone): ptr = %p  size = %d\n", im_memory_chunk_get_const_ptr (chunk3), im_memory_chunk_get_size (chunk3));

    chunk4 = im_memory_chunk_get_sub_chunk (chunk1, 64, 64, FALSE);
    chunk5 = im_memory_chunk_get_sub_chunk (chunk3, 64, 64, TRUE);

    if (!chunk4 || !chunk5) {
        printf ("Failed to get sub chunks.\n");
        return 1;
    }

    printf ("Chunk4 (sub1): ptr = %p  size = %d\n", im_memory_chunk_get_const_ptr (chunk4), im_memory_chunk_get_size (chunk4));
    printf ("Chunk5 (sub3): ptr = %p  size = %d\n", im_memory_chunk_get_const_ptr (chunk5), im_memory_chunk_get_size (chunk5));

    if (memcmp (im_memory_chunk_get_const_ptr (chunk4), im_memory_chunk_get_const_ptr (chunk5), 64) != 0) {
        printf ("chunk4 and chunk5 differ.\n");
        return 1;
    }

    if (!im_memory_chunk_ensure_size (chunk1, 512)) {
        printf ("Failed to enlarge chunk1.\n");
        return 1;
    }

    printf ("Chunk1 (enlarged): ptr = %p  size = %d\n", im_memory_chunk_get_const_ptr (chunk1), im_memory_chunk_get_size (chunk1));
    printf ("Chunk4 (sub1): ptr = %p  size = %d\n", im_memory_chunk_get_const_ptr (chunk4), im_memory_chunk_get_size (chunk4));

    im_object_unref (chunk1);
    im_object_unref (chunk2);
    im_object_unref (chunk3);
    im_object_unref (chunk4);
    im_object_unref (chunk5);

    return 0;
}
/*
vi:ts=4:nowrap:ai:expandtab
*/
